package Dominio.Entidades;

import java.io.Serializable;
import java.util.Arrays;

public class Jugada implements Serializable, Comparable<Jugada> {

    private int numero;
    // Atributos
    private Jugador jugador;
    private Pieza pieza;
    private Coordenada[] movimientos;
    private int nivel;
    private boolean ingresa = false;
    private boolean mueve = false;

    //Contructor con parametros
    public Jugada(Jugador pJugador, Pieza pPieza, String pMovimientos, boolean pIngresa) {
        this.jugador = pJugador;
        this.pieza = pPieza;
        this.ingresa = pIngresa;
        if (pMovimientos != null) {
            this.cargarMovimientos(pMovimientos);
        }
    }

    public Jugada(Jugador pJugador, Pieza pPieza, Coordenada[] pMovimientos, int pNivel, boolean pIngresa) {
        this.jugador = pJugador;
        this.pieza = pPieza;
        this.movimientos = pMovimientos;
        this.nivel = pNivel;
        this.ingresa = pIngresa;
    }

    public Jugada(int pNumero, Jugador pJugador, Pieza pPieza, Coordenada[] pMovimientos, int pNivel, boolean pIngresa) {
        this.numero = pNumero;
        this.jugador = pJugador;
        this.pieza = pPieza;
        this.movimientos = pMovimientos;
        this.nivel = pNivel;
        this.ingresa = pIngresa;
    }

    public int getNumero() {
        return numero;
    }

    public void setNumero(int pNumero) {
        this.numero = pNumero;
    }

    public Jugador getJugador() {
        return jugador;
    }

    public void setJugador(Jugador unJugador) {
        this.jugador = unJugador;
    }

    public Pieza getPieza() {
        return pieza;
    }

    public void setPieza(Pieza pPieza) {
        this.pieza = pPieza;
    }

    public Coordenada[] getMovimientos() {
        return movimientos;
    }

    public void setMovimientos(Coordenada[] pMovimientos) {
        this.movimientos = pMovimientos;
    }

    public int getNivel() {
        return nivel;
    }

    public void setNivel(int pNivel) {
        this.nivel = pNivel;
    }

    public boolean isIngresa() {
        return ingresa;
    }

    public void setIngresa(boolean pIngresa) {
        this.ingresa = pIngresa;
    }

    public boolean isMueve() {
        return mueve;
    }

    public void setMueve(boolean pMueve) {
        this.mueve = pMueve;
    }

    private boolean cargarMovimientos(String pCoordenadas) {
        boolean retorno = true;
        this.setMovimientos(new Coordenada[pCoordenadas.length() / 2]);
        Coordenada c;
        int j = 0;

        for (int i = 0; i < pCoordenadas.length() && retorno; i++) {

            char fila = pCoordenadas.charAt(i);
            int columna = Integer.parseInt(Character.toString(pCoordenadas.charAt(i + 1))) - 1;

            switch (fila) {
                case 'A':
                    c = new Coordenada(0, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'B':
                    c = new Coordenada(1, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'C':
                    c = new Coordenada(2, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'D':
                    c = new Coordenada(3, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'E':
                    c = new Coordenada(4, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'F':
                    c = new Coordenada(5, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'G':
                    c = new Coordenada(6, columna);
                    this.getMovimientos()[j] = c;
                    break;
                case 'H':
                    c = new Coordenada(7, columna);
                    this.getMovimientos()[j] = c;
                    break;
                default:
                    c = null;
                    retorno = false;
                    break;
            }
            i++;
            j++;
        }
        return retorno;
    }

    public String jugadaToString() {
        String retorno = null;
        if (this.getPieza().getTipo().equals(TipoPieza.Ficha)) {
            retorno = "I " + this.movimientosToString();
            if (this.isMueve()) {
                retorno = "M " + this.movimientosToString();
            }
            if (!this.isIngresa()) {
                retorno = "R";
            }
        } else {
            retorno = "P " + this.movimientosToString();
        }
        return retorno;
    }

    public String movimientosToString() {
        String retorno = "";//this.getMovimientos()
        if (this.getMovimientos() != null) {
            for (Coordenada coordenada : this.getMovimientos()) {
                switch (coordenada.getPosFila()) {
                    case 0:
                        retorno += "A" + (coordenada.getPosColumna() + 1);
                        break;
                    case 1:
                        retorno += "B" + (coordenada.getPosColumna() + 1);
                        break;
                    case 2:
                        retorno += "C" + (coordenada.getPosColumna() + 1);
                        break;
                    case 3:
                        retorno += "D" + (coordenada.getPosColumna() + 1);
                        break;
                    case 4:
                        retorno += "E" + (coordenada.getPosColumna() + 1);
                        break;
                    case 5:
                        retorno += "F" + (coordenada.getPosColumna() + 1);
                        break;
                    case 6:
                        retorno += "G" + (coordenada.getPosColumna() + 1);
                        break;
                    case 7:
                        retorno += "H" + (coordenada.getPosColumna() + 1);
                        break;
                }
            }
        }
        return retorno;

    }

    public boolean contienePosicion(Coordenada pPosicion) {
        boolean esta = false;
        for (int pos = 0; pos < this.getMovimientos().length && !esta; pos++) {
            Coordenada coordenada = this.getMovimientos()[pos];
            esta = coordenada.equals(pPosicion);
        }
        return esta;
    }

    /*
     * Una jugada es igual a otra si:
     *  - siendo un ladrillo tienen las mismas corredenadas en sus movimientos
     *  - siendo una ficha su ultimo movimiento son iguales
     */
    @Override
    public boolean equals(Object obj) {
        boolean existe = false;
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Jugada other = (Jugada) obj;
        if (!this.getPieza().isEsFicha()) {
            for (Coordenada coordenada : this.getMovimientos()) {
                for (Coordenada coordenada1 : other.getMovimientos()) {
                    if (coordenada.equals(coordenada1)) {
                        existe = true;
                    }
                }
                if (existe) {
                    return false;
                }
            }
        } else {
            if (other.getPieza().isEsFicha() && this.getPieza().isEsFicha()) {
                this.getPieza().getUbicacion()[0].equals(other.getPieza().getUbicacion()[0]);
            }
        }
        return true;
    }

    /**
     * Es mayor el que tiene el nivel mayor ordeno de mayor a menor
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Jugada o) {
        return o.getNumero() - this.getNumero();
    }

}
